// mapsWindowManager.js
const { BrowserWindow } = require('electron');
const path = require('path');
const fs = require('fs').promises;
const { getTimestamp, getTimestampMs } = require('./timeUtils');
// const sharp = require('sharp');
const { Jimp } = require('jimp');

class MapsWindowManager {
    constructor(app) {
        this.app = app;
        this.mapsWindow = null;
        this.currentOptions = { lat: 39.908, lng: 116.397, zoom: 15 };
        this.captureDir = '';
    }

    /**
     * 创建或获取地图窗口
     * @param {Object} options - 地图参数，包括纬度（lat）、经度（lng）和缩放级别（zoom）
     */
    async createMapsWindow(options = { lat: 39.908, lng: 116.397, zoom: 15, mode: 'manual' }) {
        this.currentOptions = options;
        this.captureDir = getTimestamp();

        if (this.mapsWindow) {
            this.mapsWindow.focus();
            // 更新地图中心和缩放
            // await this.setMapView(options.lat, options.lng, options.zoom);
            return;
        }

        this.mapsWindow = new BrowserWindow({
            width: 1200,
            height: 800,
            webPreferences: {
                nodeIntegration: false,
                contextIsolation: true,
                webviewTag: true,
                preload: path.join(__dirname, '..', 'preload.js')
            },
            deviceScaleFactor: 2
        });

        // 默认最大化窗口
        this.mapsWindow.maximize();
        this.mapsWindow.setMenu(null);

        // 构建动态的 Google Maps URL，确保是卫星图且无标注
        const { lat, lng, zoom, mode } = options;
        // const googleMapsURL = `https://www.google.com/maps/@${lat},${lng},${zoom}z/data=!5m1!1e3`; // 1e3 为卫星图模式
        const googleMapsURL =
            process.env.NODE_ENV === 'development'
                ? `http://localhost:5173/?windowType=map&lat=${lat}&lng=${lng}&zoom=${zoom}&mode=${mode}`
                : `file://${path.join(__dirname, '../../dist/index.html')}?windowType=map&lat=${lat}&lng=${lng}&zoom=${zoom}&mode=${mode}`;
        await this.mapsWindow.loadURL(googleMapsURL);

        // 打开开发者工具（可选）
        // if (process.env.NODE_ENV === 'development') {
        //     this.mapsWindow.webContents.openDevTools();
        // }

        // 监听窗口关闭事件
        this.mapsWindow.on('closed', () => {
            this.mapsWindow = null;
        });
    }

    // 关闭google map的窗口
    async closeMapsWindow(mode) {
        // 关闭并释放窗口
        if (this.mapsWindow) {
            this.mapsWindow.close();
            this.mapsWindow = null;
        }

        // 如果mode是auto，则发送ws消息到页面
        if (mode === 'auto') {
            this.app.server.broadcast(
                JSON.stringify({
                    event: 'close',
                    data: ''
                })
            );
        }
    }

    /**
     * 设置地图视图
     * @param {number} lat - 纬度
     * @param {number} lng - 经度
     * @param {number} zoom - 缩放级别
     */
    async setMapView(lat, lng, zoom) {
        if (this.mapsWindow && !this.mapsWindow.isDestroyed()) {
            const googleMapsURL =
                process.env.NODE_ENV === 'development'
                    ? `http://localhost:5173/?windowType=map&lat=${lat}&lng=${lng}&zoom=${zoom}`
                    : `file://${path.join(__dirname, '../../dist/index.html')}?windowType=map&lat=${lat}&lng=${lng}&zoom=${zoom}`;
            await this.mapsWindow.loadURL(googleMapsURL);
            await this.waitForWindowLoad();
            await this.waitForMapsIdle();
        }
    }

    /**
     * 截取地图窗口的内容，并保存到用户目录下
     */
    async captureMaps(lat, lng, alt, zoom, cropArea, scaleFactor) {
        // console.log(`lat = ${lat}, lng = ${lng}, zoom = ${zoom}`);
        if (!this.mapsWindow) {
            return { code: -1, msg: 'Google Maps 窗口未打开！' };
        }

        try {
            // 确保地图窗口已经加载完成并完全渲染
            await this.waitForMapsIdle();

            // 增加延迟，确保所有图层渲染完毕（可选）
            await new Promise((resolve) => setTimeout(resolve, 2000)); // 延迟2秒

            // 格式化时间戳
            const timestamp = getTimestampMs();
            const filename = `map_${timestamp}.png`;
            const filePath = path.join(this.app.userDataPath, 'captures', this.captureDir, filename);
            await fs.mkdir(path.dirname(filePath), { recursive: true });

            // 捕获页面内容
            const image = await this.mapsWindow.capturePage();

            // 将图片保存到指定路径
            // await fs.writeFile(filePath, image.toPNG());
            const imageBuffer = image.toPNG();

            // 如果有裁剪区域，则裁剪图片
            if (cropArea) {
                const { left, top, right, bottom } = cropArea;
                // 计算裁剪区域的宽度和高度（考虑 DPI 缩放）
                const scaledLeft = left * scaleFactor;
                const scaledTop = top * scaleFactor;
                const scaledRight = right * scaleFactor;
                const scaledBottom = bottom * scaleFactor;

                const scaledWidth = image.getSize().width - scaledLeft - scaledRight;
                const scaledHeight = image.getSize().height - scaledTop - scaledBottom;

                // 输出调试信息
                console.log('原始裁剪区域:', cropArea);
                console.log('缩放比例:', scaleFactor);
                console.log('调整后的裁剪区域:', {
                    left: scaledLeft,
                    top: scaledTop,
                    width: scaledWidth,
                    height: scaledHeight
                });

                // 使用 sharp 裁剪图片
                // await sharp(imageBuffer)
                //     .extract({ left: scaledLeft, top: scaledTop, width: scaledWidth, height: scaledHeight })
                //     .toFile(filePath);
                // 使用 Jimp 实现裁剪
                const jimpImage = await Jimp.read(imageBuffer);
                jimpImage.crop({
                    x: Math.round(scaledLeft),
                    y: Math.round(scaledTop),
                    w: Math.round(scaledWidth),
                    h: Math.round(scaledHeight)
                });
                await jimpImage.write(filePath);
            } else {
                await fs.writeFile(filePath, imageBuffer);
            }

            // 将lat、lng、zoom信息保存到文件
            let center = {
                centerLat: lat,
                centerLng: lng,
                zoom: parseInt(zoom),
                altitude: alt
            };
            let jsonPath = path.join(this.app.userDataPath, 'captures', this.captureDir, `map_${timestamp}.json`);
            await fs.writeFile(jsonPath, JSON.stringify(center));
            console.log(`图片已成功保存到: ${filePath}`);
            return { code: 0, msg: `地图已保存！` };
        } catch (error) {
            console.error('截取地图失败:', error);
            return { code: -1, msg: '截取地图失败' };
        }
    }

    /**
     * 等待地图窗口加载完成
     * @returns {Promise}
     */
    waitForWindowLoad() {
        return new Promise((resolve, reject) => {
            if (this.mapsWindow.webContents.isLoading()) {
                console.log('mapsWindow is loading!');
                this.mapsWindow.webContents.on('did-finish-load', () => {
                    resolve();
                });
                // 设置超时以防止无限等待
                setTimeout(() => {
                    reject(new Error('地图窗口加载超时'));
                }, 10000); // 10 秒
            } else {
                resolve();
            }
        });
    }

    /**
     * 确保 Google Maps 完全加载并渲染完毕
     * @returns {Promise}
     */
    waitForMapsIdle() {
        return new Promise((resolve, reject) => {
            const timeout = setTimeout(() => {
                reject(new Error('等待地图 idle 超时'));
            }, 10000); // 10 秒

            this.mapsWindow.webContents
                .executeJavaScript(
                    `new Promise((res, rej) => {
                        if (typeof google === 'undefined' || typeof google.maps === 'undefined') {
                            res(true); // 如果 Google Maps API 尚未加载，直接解析
                        } else {
                            const mapInstance = Array.from(document.querySelectorAll('div')).find(div => div.__gm_map);
                            if (mapInstance && mapInstance.__gm_map) {
                            google.maps.event.addListenerOnce(mapInstance.__gm_map, 'idle', () => {
                                res(true);
                            });
                            } else {
                                res(true); // 如果未找到地图实例，直接解析
                            }
                        }
                    });`
                )
                .then(() => {
                    clearTimeout(timeout);
                    resolve();
                })
                .catch((err) => {
                    clearTimeout(timeout);
                    reject(err);
                });
        });
    }

    /**
     * 自定义文件名清理函数
     * 将非法字符替换为下划线 '_'
     * @param {string} filename - 原始文件名
     * @returns {string} - 清理后的文件名
     */
    sanitizeFilename(filename) {
        return filename.replace(/[^a-z0-9_\-\.]/gi, '_');
    }

    // 获取捕捉的所有目录列表
    async getDirs() {
        const captureDir = path.join(this.app.userDataPath, 'captures');
        try {
            const files = await fs.readdir(captureDir, { withFileTypes: true });

            // 过滤出目录
            const directories = files.filter((file) => file.isDirectory()).map((dir) => dir.name);

            // 获取每个目录的创建时间
            const directoriesWithStats = await Promise.all(
                directories.map(async (dir) => {
                    const dirPath = path.join(captureDir, dir);
                    const stats = await fs.stat(dirPath);
                    return {
                        name: dir,
                        birthtime: stats.birthtime // 目录的创建时间
                    };
                })
            );

            // 按创建时间倒序排序
            directoriesWithStats.sort((a, b) => b.birthtime - a.birthtime);

            // 提取排序后的目录名称
            const sortedDirectories = directoriesWithStats.map((dir) => dir.name);

            return { code: 0, msg: sortedDirectories };
        } catch (error) {
            console.error('获取目录列表失败:', error);
            return { code: -1, msg: error.message };
        }
    }
    // 获取目录中的所有截图信息
    async getCaptures(dir) {
        const captureDir = path.join(this.app.userDataPath, 'captures');

        try {
            const files = await fs.readdir(path.join(captureDir, dir));
            const imageFiles = files.filter((file) => file.endsWith('.png'));
            const screenshots = [];

            for (const imageFile of imageFiles) {
                const imagePath = path.join(captureDir, dir, imageFile);
                const metadataFile = imageFile.replace('.png', '.json');
                const metadataPath = path.join(captureDir, dir, metadataFile);

                try {
                    const metadataRaw = await fs.readFile(metadataPath, 'utf-8');
                    const metadata = JSON.parse(metadataRaw);
                    screenshots.push({ imageFile, imagePath, metadata });
                } catch (err) {
                    console.warn(`无法读取元数据文件: ${metadataPath}, 跳过 ${imageFile}`);
                }
            }
            return { code: 0, msg: screenshots };
        } catch (error) {
            console.error('读取输入目录时出错:', error);
            return { code: -1, msg: error.message };
        }
    }

    // 删除capture images的目录
    async deleteCaptures(dir) {
        const captureDir = path.join(this.app.userDataPath, 'captures', dir);
        let result;

        try {
            await fs.access(captureDir);
            if (dir !== '') {
                await fs.rm(captureDir, { recursive: true, force: true });
                result = { code: 0, msg: `Directory '${dir}' deleted successfully.` };
            } else {
                result = { code: -1, msg: `Directory name is invalid.` };
            }
        } catch (err) {
            result = { code: -1, msg: `Directory '${dir}' does not exist or an error occurred: ${err.message}` };
        }

        return result;
    }

    // 模拟鼠标拖拽事件
    simulateDrag_v2(startX, startY, endX, endY) {
        console.log(`simulateDrag startX = ${startX}, startY = ${startY}, endX = ${endX}, endY = ${endY}`);

        // 获取窗口在屏幕上的位置
        const [windowX, windowY] = this.mapsWindow.getPosition();

        // 转换窗口内坐标到屏幕坐标
        const screenStartX = startX + windowX;
        const screenStartY = startY + windowY;
        const screenEndX = endX + windowX;
        const screenEndY = endY + windowY;

        // 移动鼠标到起始位置
        robot.moveMouse(screenStartX, screenStartY);

        // 按下鼠标左键
        robot.mouseToggle('down', 'left');

        // 拖拽鼠标到结束位置
        robot.dragMouse(screenEndX, screenEndY);

        // 释放鼠标左键
        robot.mouseToggle('up', 'left');
    }

    // 模拟鼠标拖拽事件
    async simulateDrag_v1(startX, startY, endX, endY) {
        console.log(`simulateDrag startX = ${startX}, startY = ${startY}, endX = ${endX}, endY = ${endY}`);
        const webContents = this.mapsWindow.webContents;

        // 模拟鼠标按下
        webContents.sendInputEvent({
            type: 'mouseDown',
            x: startX,
            y: startY,
            button: 'left' // 左键
        });

        // 模拟鼠标移动（分多次移动）
        const steps = 10; // 移动的步数
        const dx = (endX - startX) / steps; // X 方向的步长
        const dy = (endY - startY) / steps; // Y 方向的步长

        for (let i = 1; i <= steps; i++) {
            const currentX = startX + dx * i;
            const currentY = startY + dy * i;

            webContents.sendInputEvent({
                type: 'mouseMove',
                x: currentX,
                y: currentY,
                button: 'left' // 左键
            });

            // 添加延迟，模拟真实的鼠标移动(50ms延迟)
            await new Promise((resolve) => setTimeout(resolve, 100));
        }

        // 模拟鼠标释放
        webContents.sendInputEvent({
            type: 'mouseUp',
            x: endX,
            y: endY,
            button: 'left' // 左键
        });

        // 添加延迟，模拟真实的鼠标移动(1000ms延迟)
        await new Promise((resolve) => setTimeout(resolve, 500));
    }
}

// 导出全局唯一的 MapsWindowManager 实例
// const mapsWindowManager = new MapsWindowManager();
module.exports = { MapsWindowManager };
